package com.sxran.im.controller;

import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.sxran.im.bean.GenerateConversationIdReqBody;
import com.sxran.im.bean.MessageReqBody;
import com.sxran.im.bean.NotificationBody;
import com.sxran.im.bean.UserMessageData;
import com.sxran.im.dao.*;
import com.sxran.im.feign.ImApiFeign;
import com.sxran.im.feign.dto.*;
import com.sxran.im.handler.*;
import com.sxran.im.info.*;
import com.sxran.im.service.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 */
@CrossOrigin(origins = "*")
@RestController
@Slf4j
public class ChatController {
	@Resource
	private ImApiFeign imApiFeign;
	@Resource
	private ImConversationMapper imConversationMapper;
	@Resource
	private ChatService chatService;
	@Resource
	private ConversationService conversationService;
	@Resource
	private ImMsgExtrasMapper imMsgExtrasMapper;
	@Resource
	private UserGroupService userGroupService;
	@Resource
	private ImChatBodyMapper imChatBodyMapper;
	///////////////////////////////////////////////////////////
	////                      带有通知的接口
	////
	////////////////////////////////////////////////////////////

	/**
	 * 发送消息
	 * @see ChatBeforeCmdHandler
	 * @param json
	 * @return
	 */
	@PostMapping("/api/chat/chatMessage")
	public CommonResult<Boolean> chatMessage(@RequestBody ImChatBody json) {
		log.info("这里是发消息之前的内容,可以对他做内容的过滤。 \n 也可以把他记录到数据库中存储,但是不保证对方一定接受到,因为这是前置操作,也就是说中途可能服务器拒绝发送 \n 如果要做到百分之百准确，建议再收到消息之后再修改一下状态。 ={}",json);
		// 存会话表内容。
		String conversationId = json.getConversation();
		Integer chatType = json.getChatType();
		Integer msgType = json.getMsgType();
		String to = null;
		String string = json.getContent().toString();
		json.setMsgState(100); // 发送成功。
		// 判断敏感词
		if(string.contains("涉黄")){
			json.setMsgState(-200);
		}else{
			json.setContent(string);
			JSONObject extras = json.getExtras();
			if(extras != null){
				json.setExtras0(extras.toJSONString());
			}
			// 存聊天表。
			imChatBodyMapper.insert(json);
		}
		switch (msgType){
			case 0 :
				string = StrUtil.maxLength(string,499);
				break;
			case 7 :
				string = "【语音通话】";
				break;
			case 8 :
				string = "【视频通话】";
				break;
			default :
				string = "【特殊消息】";
				break;
		}
		//
		String fromId = json.getFromId();
		List<String> userIds = null;
		// 标题和图标的设置。
		if(chatType == 1){
			to = json.getGroupId();
			userIds = userGroupService.getUserIds(to);
			for (String userId : userIds) {
				if (!StrUtil.equals(fromId, userId)) {
					// 给所有群成员，更新一下会话表。
					conversationService.updateOrInsert(userId,conversationId, string, chatType,to,1);
				}
			}
			// 自己的会话表,不添加未读计数
			conversationService.updateOrInsert(fromId,conversationId, string, chatType,to,0);
		}else if (chatType == 2){
			to = json.getToId();
			userIds = Arrays.asList(to);
			conversationService.updateOrInsert(to,conversationId, string, chatType,fromId,1);
			// 自己的会话表,不添加未读计数
			conversationService.updateOrInsert(fromId,conversationId, string, chatType,to,0);
		}
		// 【BUG】接收方第一次收到消息，会话列表标题和头像就是空的
		ImConversation newConversationObj = new ImConversation();
		newConversationObj.setId(conversationId);
		conversationService.fillConversation(chatType,to,newConversationObj);
		json.setNewConversationObj(newConversationObj);
		// 通知消息内容
		ImChatMessageDto chatMessageDto = new ImChatMessageDto();
		chatMessageDto.setChatBody(json);
		imApiFeign.batchChatUser( userIds ,chatMessageDto);
		return  CommonResult.success(true);
	}
	/**
	 * 撤回消息
	 * @see RevokeMessageCmdHandler
	 * @param json
	 * @return
	 */
	@PostMapping("/api/chat/revokeMessage")
	public CommonResult<Boolean> revokeMessage(@RequestBody ImChatBody json){
		json.setContent("[此消息已被撤回]");
		return  updateMessage(json);
	}
	/**
	 * 修改消息
	 * @see 暂时没有... 新加的功能...
	 * @param json
	 * @return
	 */
	@PostMapping("/api/chat/updateMessage")
	public CommonResult<Boolean> updateMessage(@RequestBody ImChatBody json){
		// 对消息表的消息整体设置状态。
		ImChatBody imChatBody = imChatBodyMapper.selectById(json.getId());
		String extras0 = imChatBody.getExtras0();
		JSONObject jsonObject = JSONObject.parseObject(extras0);
		jsonObject.put("isRevoke",1);
		imChatBody.setExtras0(jsonObject.toJSONString());
		imChatBodyMapper.updateById(imChatBody);
		// 通知其他人，将消息实时的撤回。

		String groupId = imChatBody.getGroupId();
		String[] targetList = null;
		if (StrUtil.isBlank(groupId)) {
			targetList = new String[]{
					imChatBody.getToId(),
					imChatBody.getFromId()
			};
		}else{
			List<String> userIds = userGroupService.getUserIds(groupId);
			targetList = ArrayUtil.toArray(userIds,String.class);
		}
		// 通知消息内容
		ImRevokeMessageDto revokeMessageDto = new ImRevokeMessageDto();
		revokeMessageDto.setContent( String.valueOf(json.getContent()) );
		revokeMessageDto.setConversation(imChatBody.getConversation());
		revokeMessageDto.setMessageId(imChatBody.getId());
		imApiFeign.batchChatUser(Arrays.asList(targetList),revokeMessageDto);
		return  CommonResult.success(true);
	}
	///////////////////////////////////////////////////////////
	////		传统的im业务...
	////
	////////////////////////////////////////////////////////////

	/**
	 * 获得消息
	 * @see GetMessageCmdHandler
	 * @param json
	 * @return
	 */
	@PostMapping("/api/chat/getMessage")
	public CommonResult<UserMessageData> getMessage(@RequestBody MessageReqBody json){
		// 执行结果
		List<ImChatBody> imChatList = chatService.selectList(json);
		//
		UserMessageData userMessageData = new UserMessageData();
		Map<String, List<ImChatBody>> friends = userMessageData.getFriends();
		Map<String, List<ImChatBody>> groups = userMessageData.getGroups();
		// 私聊信息。
		for (ImChatBody imChatBody : imChatList) {
			String toId = imChatBody.getToId();
			// 好友。
			if (StrUtil.isNotEmpty(toId)) {
				List<ImChatBody> imChatBodies = friends.get(toId);
				if(imChatBodies == null){
					imChatBodies = new ArrayList<>();
				}
				imChatBodies.add(imChatBody);
				friends.put(toId,imChatBodies);
			}

		}

		// 群聊信息。
		String userId = json.getUserId();
		List<ImUserGroup> imUserGroups = userGroupService.selectList(userId);
		for (ImUserGroup imUserGroup : imUserGroups) {
			String groupId = imUserGroup.getGid();
			// 群聊。
			if (StrUtil.isNotEmpty(groupId)) {
//                List<ImChatBody> imChatBodies = groups.get(groupId);
//                if(imChatBodies == null){
//                    imChatBodies = new ArrayList<>();
//                }
//                imChatBodies.add(imChatBody);
				MessageReqBody groupJson = new MessageReqBody();
				groupJson.setGroupId(groupId);
				List<ImChatBody> groupList = (List<ImChatBody>) chatService.selectList(groupJson);
				groups.put(groupId,groupList);
			}
		}
		return  CommonResult.success(userMessageData);
	}

	/**
	 *  获得消息列表
	 * @see GetMessageListCmdHandler
	 * @param json
	 * @return
	 */
	@PostMapping("/api/chat/getMessageList")
	public CommonResult<List<ImChatBody>> getMessageList(@RequestBody MessageReqBody json){
		List<ImChatBody> imChatBodies = chatService.selectList(json);
		return  CommonResult.success(imChatBodies);
	}

	/**
	 * 删除消息
	 * @see DeleteMessageCmdHandler
	 * @param json
	 * @return
	 */
	@PostMapping("/api/chat/deleteMessage")
	public CommonResult<Integer> deleteMessage(@RequestBody ImMsgExtras json){
        int i = imMsgExtrasMapper.updateById(json);
        // 根据后台规则 生成会话id 等 内容
		return  CommonResult.success(i);
	}





	/**
	 * 根据后台规则 生成会话id 等 内容
	 * @see GenerateConversationCmdHandler
	 * @param bean
	 * @return
	 */
	@PostMapping("/api/chat/generateConversation")
	public CommonResult<ImConversation> generateConversation(@RequestBody GenerateConversationIdReqBody bean){
		String conversation = bean.getConversation();
		ImConversation newConversationObj = new ImConversation();
		newConversationObj.setId(conversation);
		conversationService.fillConversation(bean.getChatType(),bean.getOriginalTo(),newConversationObj);
		// 根据后台规则 生成会话id 等 内容
		return  CommonResult.success(newConversationObj);
	}
	/**
	 * @see GetConversationListCmdHandler
	 * @param userId
	 * @return
	 */
	@PostMapping("/api/chat/myConversation")
	public CommonResult<List<ImConversation>> myConversation(@RequestParam("userId") String userId){
		String curUserId = userId ;//ImController.getCurUserId();


		LambdaQueryWrapper<ImConversation> queryWrapper = new LambdaQueryWrapper<>();
		queryWrapper.eq(ImConversation::getUserId,curUserId);
		// 排序
		queryWrapper.orderByDesc(ImConversation::getUpdateTime);
		// 执行结果
		List<ImConversation> list = null;
		boolean isPage = false;
		if(isPage){  // 先不分页的操作.
//            IPage<ImChatBody> page = new Page<>(offset, count);
//            list = imConversationMapper.selectList(page,queryWrapper);
		}else{
			list = imConversationMapper.selectList(queryWrapper);
			list.forEach(x->{
				String id = x.getId();
				MessageReqBody req = new MessageReqBody();
				req.setConversation(id);
				req.setOffset(1);
				req.setCount(5); // 前端20条占啦4个屏幕啦，用5条数据。
				x.setMsgList( chatService.selectList(req) );
			});
		}

		return CommonResult.success(list);
	}
	/**
	 * 成功接收消息>>> 接收消息的人调用这个接口.
	 * @see ChatBeforeCmdHandler
	 * @param req
	 * @return
	 */
	@PostMapping("/api/chat/ackMessage")
	public CommonResult<Integer> ackMessage(@RequestBody ImChatBody req) {
		ImChatBody json = new ImChatBody();
		json.setId(req.getId());
		json.setMsgState(200); // 接收成功。
		int i = imChatBodyMapper.updateById(json);
		return  CommonResult.success(i);
	}
}
